package org.example.netty.test.nio.java;

import lombok.extern.slf4j.Slf4j;
import org.example.netty.test.bio.NioDemoConfig;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * @author zp
 * @version 1.0
 * @description: 使用NIO的方式 读取拷贝文件
 * 查看效果 去查看target目录下的文件 如果不想查看target目录 可以直接写绝对目录
 * @date 2023/2/20 19:08
 */
@Slf4j
public class FileNIOCopyDemo {
    public static void main(String[] args) throws IOException {
        nioCopyResouceFile();
    }

    /**
     * @description: 复制两个资源目录下的文件
     * @author zp
     * @date: 2023/2/20 19:09
     */
    public static void nioCopyResouceFile() throws IOException {
        //获取源文件地址
        String sourcePath = NioDemoConfig.FILE_RESOURCE_SRC_PATH;
        String srcDecodePath = IOUtil.getResourcePath(sourcePath);
        log.info("srcDecodePath=" + srcDecodePath);
        //目标
        String destPath = NioDemoConfig.FILE_RESOURCE_DEST_PATH;
        String destDecodePath = IOUtil.builderResourcePath(destPath);
        log.info("destDecodePath=" + destDecodePath);
        //复制文件
        nioCopyFile(srcDecodePath, destDecodePath);
    }

    private static void nioCopyFile(String srcDecodePath, String destDecodePath) throws IOException {
        File srcFile = new File(srcDecodePath);
        File destFile = new File(destDecodePath);
        try {
            //如果目标文件不存在，则新建
            if (!destFile.exists()) {
                destFile.createNewFile();
            }
            long startTime = System.currentTimeMillis();

            FileInputStream fis = null;

            FileOutputStream fos = null;
            //输入通道
            FileChannel inChannel = null;
            //输出通道
            FileChannel outchannel = null;
            try {
                fis = new FileInputStream(srcFile);
                fos = new FileOutputStream(destFile);
                inChannel = fis.getChannel();
                outchannel = fos.getChannel();
                int length = -1;
                //新建buf，处于写入模式
                ByteBuffer buf = ByteBuffer.allocate(1024);
                //从输入通道读取到buf
                while ((length = inChannel.read(buf)) != -1) {
                    //buf第一次模式切换：翻转buf，从写入模式变成读取模式
                    buf.flip();
                    int outlength = 0;
                    //将buf写入到输出的通道
                    while ((outlength = outchannel.write(buf)) != 0) {
                        System.out.println("写入的字节数：" + outlength);
                    }
                    //buf第二次模式切换：清除buf，变成写入模式
                    buf.clear();
                }
                //强制刷新到磁盘
                outchannel.force(true);

            } finally {
                //关闭所有的可关闭对象
                IOUtil.closeQuietly(outchannel);
                IOUtil.closeQuietly(fos);
                IOUtil.closeQuietly(inChannel);
                IOUtil.closeQuietly(fis);
            }
            long endTime = System.currentTimeMillis();
            log.info("base复制毫秒数：" + (endTime - startTime));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
